#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   OBU_pack_test.py
@Time    :   2025/04/17 13:31:28
@Author  :   YangLiang 
@Version :   1.0
@Contact :   yangl@genvict.com
@License :   (C)Copyright 2022-2025
@Desc    :   OBU分包 组包测试
'''

from pytest_assume.plugin import assume
import pytest
import logging
import time
from commDriver.TS_CAN import *
import allure
import sys
from commDriver.ZEEKR_issuance import ZEEKR_Issuer
import random
sys.dont_write_bytecode = True
import Set_up


class Test_OBU_pack:
    '''
    OBU组包测试
    '''


    @allure.severity('normal')
    @allure.title('检查OBU接收完整报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收完整报文后ETCActiveRespFromOBU状态=OK')
    @pytest.mark.repeat(1)
    def test_ETCActiveRespFromOBU_OK(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据
        with allure.step(f'第{iStep}步:发送完整数据 # ETCActiveRespFromOBU状态=0x01(OK)'):
            for packet in packets:
                Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                time.sleep(0.01)
            logging.info('发送完成,等待0.5s,查看OBU组包结果')
            time.sleep(0.5)
            # 读取OBU组包结果
            iStep, ETCActiveRespFromOBU, messageCount = Driver['CAN'].getETCActiveRespFromOBU(iStep)
            with assume: assert ETCActiveRespFromOBU == 0x01, logging.error('OBU组包结果应该是0x01,实际为：%s' % ETCActiveRespFromOBU)

    @allure.severity('normal')
    @allure.severity('normal')  
    @allure.severity('normal')
    @allure.title('检查OBU接收缺少第一帧报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收缺少第一帧报文后ETCActiveRespFromOBU状态=NOK')
    def test_ETCActiveRespFromOBU_NOK_lostFirst(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据
        with allure.step(f'第{iStep}步:发送完整数据 # ETCActiveRespFromOBU状态=0x01(OK)'):
            for packet in packets[1:]:
                Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                time.sleep(0.01)
            time.sleep(0.5)
            # 读取OBU默认状态下开关状态
            iStep, ETCActiveRespFromOBU, messageCount = Driver['CAN'].getETCActiveRespFromOBU(iStep)
            with assume: assert ETCActiveRespFromOBU == 0x02, logging.error('OBU组包结果应该是0x02,实际为：%s' % ETCActiveRespFromOBU)
            with assume: assert messageCount == 3, logging.error('OBU发送组包结果信号帧数应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU接收缺少最后一帧报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收缺少最后一帧报文后ETCActiveRespFromOBU状态=NOK')
    def test_ETCActiveRespFromOBU_NOK_lostLast(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据(缺少最后一帧)
        with allure.step(f'第{iStep}步:发送缺少最后一帧的数据 # ETCActiveRespFromOBU状态=0x02(NOK)'):
            for packet in packets[:-1]:  # 不发送最后一帧
                Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                time.sleep(0.01)
            time.sleep(0.5)
            # 读取OBU默认状态下开关状态
            iStep, ETCActiveRespFromOBU, messageCount = Driver['CAN'].getETCActiveRespFromOBU(iStep)
            with assume: assert ETCActiveRespFromOBU == 0x02, logging.error('OBU组包结果应该是0x02,实际为：%s' % ETCActiveRespFromOBU)
            with assume: assert messageCount == 3, logging.error('OBU发送组包结果信号帧数应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU接收缺少中间帧报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收缺少中间帧报文后ETCActiveRespFromOBU状态=NOK')
    def test_ETCActiveRespFromOBU_NOK_lostMiddle(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据(缺少中间帧)
        with allure.step(f'第{iStep}步:发送缺少中间帧的数据 # ETCActiveRespFromOBU状态=0x02(NOK)'):
            for i, packet in enumerate(packets):
                if i != len(packets)//2:  # 跳过中间帧
                    Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                    time.sleep(0.01)
            time.sleep(0.5)
            # 读取OBU默认状态下开关状态
            iStep, ETCActiveRespFromOBU, messageCount = Driver['CAN'].getETCActiveRespFromOBU(iStep)
            with assume: assert ETCActiveRespFromOBU == 0x02, logging.error('OBU组包结果应该是0x02,实际为：%s' % ETCActiveRespFromOBU)
            with assume: assert messageCount == 3, logging.error('OBU发送组包结果信号帧数应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU接收随机缺少一帧报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收随机缺少一帧报文后ETCActiveRespFromOBU状态=NOK')
    def test_ETCActiveRespFromOBU_NOK_lostRandom(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 随机选择要跳过的帧
        skip_index = random.randint(0, len(packets)-1)
        # 发送数据(随机跳过一帧)
        with allure.step(f'第{iStep}步:发送随机缺少一帧的数据(跳过第{skip_index+1}帧) # ETCActiveRespFromOBU状态=0x02(NOK)'):
            for i, packet in enumerate(packets):
                if i != skip_index:  # 跳过随机选择的一帧
                    Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                    time.sleep(0.01)
            time.sleep(0.5)
            # 读取OBU默认状态下开关状态
            iStep, ETCActiveRespFromOBU, messageCount = Driver['CAN'].getETCActiveRespFromOBU(iStep)
            with assume: assert ETCActiveRespFromOBU == 0x02, logging.error('OBU组包结果应该是0x02,实际为：%s' % ETCActiveRespFromOBU)
            with assume: assert messageCount == 3, logging.error('OBU发送组包结果信号帧数应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU接收完整报文后ETCActiveRespFromOBU发送数量')
    @allure.description('检查OBU接收完整报文后ETCActiveRespFromOBU发送数量=3')
    def test_ETCActiveRespFromOBU_OK_Count(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据
        with allure.step(f'第{iStep}步:发送完整数据 # ETCActiveRespFromOBUs count=3'):
            for packet in packets:
                Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                time.sleep(0.01)
            time.sleep(0.5)
            iStep, messageCount, data = Driver['CAN'].GetMessageCount(iStep, 0x312, 2)
            with assume: assert messageCount == 3, logging.error('ETCActiveRespFromOBU count应该是3,实际为：%s' % ETCActiveRespFromOBU)
            with assume: assert messageCount == 3, logging.error('OBU发送组包结果信号帧数应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU接收缺少第一帧报文后ETCActiveRespFromOBU状态')
    @allure.description('检查OBU接收缺少第一帧报文后ETCActiveRespFromOBU状态=NOK')
    def test_ETCActiveRespFromOBU_NOK_Count(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_data = [0x11] * 23
        packets = Driver['CAN'].unpack(send_data)
        # 发送数据
        with allure.step(f'第{iStep}步:发送完整数据 # ETCActiveRespFromOBU状态=0x01(OK)'):
            for packet in packets[1:]:
                Driver['CAN'].TransmitData(Set_up.ActiveReqID, packet, Set_up.CAN_Type)
                time.sleep(0.01)
            time.sleep(0.5)
            iStep, messageCount, data = Driver['CAN'].GetMessageCount(iStep, 0x312, 2)
            with assume: assert messageCount == 3, logging.error('ETCActiveRespFromOBU count应该是3,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU收到ETCActiveRespFromHMI=1,OBU不重发')
    @allure.description('检查OBU收到ETCActiveRespFromHMI=1,OBU不重发')
    @pytest.mark.repeat(1)
    def test_ETCActiveRespFromHMI_OK(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_Data = [0x33, 0x01, 0x80, 0x01, 0xa2, 0x22]
        # 发送数据
        with allure.step(f'第{iStep}步:接收OBU响应 # '):
            receive_data = Driver['CAN'].ZEEKR_Send_Recv(send_Data)
            iStep += 1
            Driver['CAN'].ClearBuffer()
        with allure.step(f'第{iStep}步:发送ETCActiveRespFromHMI = 1 # '):
            iStep = Driver['CAN'].Set_ETCActiveRespFromHMI(iStep, 'Sussess')
        # 读取OBU是否重发
        with allure.step(f'第{iStep}步:读取OBU是否重发 # 未重发'):
            iStep, messageCount, data = Driver['CAN'].GetMessageCount(iStep, 0x0F0, 0.2)
            with assume: assert messageCount == 0, logging.error('OBU不重发,0x0F0帧数应该为0,实际为：%s' % messageCount)
    
    @allure.severity('normal')
    @allure.title('检查OBU收到ETCActiveRespFromHMI=2,OBU应重发')
    @allure.description('检查OBU收到ETCActiveRespFromHMI=2,OBU应重发')
    @pytest.mark.repeat(1)
    def test_ETCActiveRespFromHMI_NOK(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_Data = [0x33, 0x01, 0x80, 0x01, 0xa2, 0x22]
        # 发送数据
        with allure.step(f'第{iStep}步:接收OBU响应 # '):
            receive_data = Driver['CAN'].ZEEKR_Send_Recv(send_Data)
            iStep += 1
            Driver['CAN'].ClearBuffer()
        with allure.step(f'第{iStep}步:发送ETCActiveRespFromHMI = 1 # '):
            iStep = Driver['CAN'].Set_ETCActiveRespFromHMI(iStep, 'Fail')
        # 读取OBU是否重发
        with allure.step(f'第{iStep}步:读取OBU是否重发 # 应重发'):
            iStep, messageCount, data = Driver['CAN'].GetMessageCount(iStep, 0x0F0, 1)
            with assume: assert messageCount == 4, logging.error('OBU重发,0x0F0帧数应该=2,实际为：%s' % messageCount)

    @allure.severity('normal')
    @allure.title('检查OBU 200ms内未收到ETCActiveRespFromHMI数据,OBU应重发')
    @allure.description('检查OBU 200ms内未收到ETCActiveRespFromHMI数据,OBU应重发')
    @pytest.mark.repeat(1)
    def test_ETCActiveRespFromHMI_Out_200ms(self, action, Driver):
        iStep = 1
        # 数据拆包
        send_Data = [0x33, 0x01, 0x80, 0x01, 0xa2, 0x22]
        # 发送数据
        with allure.step(f'第{iStep}步:接收OBU响应 # '):
            receive_data = Driver['CAN'].ZEEKR_Send_Recv(send_Data)
            iStep += 1
            Driver['CAN'].ClearBuffer()
        logging.info('等待220ms,OBU未收到ETCActiveRespFromHMI数据')
        time.sleep(0.22)  # 等待220ms,OBU未收到ETCActiveRespFromHMI数据,OBU应重发
        # 读取OBU是否重发
        with allure.step(f'第{iStep}步:读取OBU是否重发 # 应重发'):
            iStep, messageCount, data = Driver['CAN'].GetMessageCount(iStep, 0x0F0, 1)
            with assume: assert messageCount == 4, logging.error('OBU重发,0x0F0帧数应该=2,实际为：%s' % messageCount)
